package middleware

import (
	"fmt"
	"net/http"
	"strings"

	"mall/common/errorx"
	"mall/common/jwtx"

	log "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/stores/redis"
	"github.com/zeromicro/go-zero/rest/httpx"
)

type CheckUriMiddleware struct {
	BizRedis *redis.Redis
}

func NewCheckUriMiddleware(BizRedis *redis.Redis) *CheckUriMiddleware {
	return &CheckUriMiddleware{BizRedis: BizRedis}
}

func (m *CheckUriMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 判断请求header中是否携带了x-user-id
		userId, err := jwtx.GetUserId(r.Context())
		if err != nil {
			log.Info(fmt.Sprintf("CheckUriMiddleware not existed userId: %v, access path exception: %+v", userId, err))
			httpx.Error(w, errorx.Error(errorx.ERROR_NOT_EXIST_PARAME_X_USER_ID, ""))
			return
		}
		var path string = r.URL.Path
		if path == "/api/backend/user/currentUser" || path == "/api/backend/role/queryMenuByRoleId" {
			// Passthrough to next handler if need
			next(w, r)
		} else {
			// 获取用户能访问的api
			apis, err := m.BizRedis.Get(fmt.Sprintf("backend:menu:user%d", userId))
			if err != nil {
				log.Info(fmt.Sprintf("CheckUriMiddleware userId: %v, get redis connection exception", userId))
				httpx.Error(w, errorx.Error(errorx.ERROR_REDIS_CONNECT_EXCEPTION, ""))
				return
			}

			if len(strings.TrimSpace(apis)) == 0 {
				log.Info(fmt.Sprintf("CheckUriMiddleware apis not existed, userId: %v, not login yet", userId))
				httpx.Error(w, errorx.Error(errorx.ERROR_NOT_LOGIN, fmt.Sprintf("用户userId: %v 还没有登录，请先登录", userId)))
				return
			}

			backendApis := strings.Split(apis, ",")
			var authorized bool
			for _, api := range backendApis {
				if api == path {
					authorized = true
					break
				}
			}

			if authorized {
				next(w, r)
			} else {
				log.Info(fmt.Sprintf("CheckUriMiddleware userId: %v, access path: %s, no authority exception", userId, path))
				httpx.Error(w, errorx.Error(
					errorx.ERROR_NOT_ACCESS_AUTHORITY,
					fmt.Sprintf("用户userId: %v，没有访问: %s 路径的权限，请联系管理员", userId, path),
				))
				return
			}
		}
	}
}
